/////////////////////////////////////////////////////////////////////////////
// Name:        main.cpp
// Purpose:     Stratlas main
// Author:      Greg Kennedy
// Id:          $Id: main.cpp,v 1.00 2008/03/16 21:39:20 PC Exp $
// Copyright:   (c) 2008 Greg Kennedy
// Licence:     GPL v3
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

#include "common.h"
#include "main.h"

#ifdef DEFINE_SAVE_BMP
#include "out/out_bmp.h"
#endif

#ifdef DEFINE_SAVE_PNG
#include "out/out_png.h"
#endif

#ifdef DEFINE_LOAD_WARCRAFT
#include "in/in_warcraft.h"
#endif

#ifdef DEFINE_LOAD_WAR2
#include "in/in_war2.h"
#endif

#ifdef DEFINE_LOAD_CNCTD
#include "in/in_cnctd.h"
#endif

#ifdef DEFINE_LOAD_TOTALA
#include "in/in_totala.h"
#endif

// -*- C++ -*- generated by wxGlade 0.6.3 on Thu Apr 03 11:24:46 2008

// begin wxGlade: ::extracode
// end wxGlade

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

// control ids
enum
{
    Stratlas_Quit = 1,
    Stratlas_About,
    Stratlas_Clear,
    Stratlas_Add,
    Stratlas_Remove,
    Stratlas_Process,
    Stratlas_Worklist,
    Stratlas_Filelist
};

// Define a new application type, each program should derive a class from wxApp
class StratlasApp : public wxApp
{
public:
    // override base class virtuals
    // ----------------------------

    // this one is called on application startup and is a good place for the app
    // initialization (doing it here and not in the ctor allows to have an error
    // return: if OnInit() returns false, the application terminates)
    virtual bool OnInit();
};
// ----------------------------------------------------------------------------
// misc macros
// ----------------------------------------------------------------------------

IMPLEMENT_APP(StratlasApp)

// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_BUTTON(Stratlas_Add, MyFrame::OnButtonAdd)
    EVT_BUTTON(Stratlas_Remove, MyFrame::OnButtonRemove)
    EVT_BUTTON(Stratlas_Process, MyFrame::OnButtonProcess)
    EVT_BUTTON(Stratlas_Clear, MyFrame::OnButtonClear)

    EVT_MENU(Stratlas_Quit, MyFrame::OnMenuQuit)
    EVT_MENU(Stratlas_About, MyFrame::OnMenuAbout)

    EVT_LISTBOX_DCLICK(Stratlas_Worklist, MyFrame::OnWorklist)
    EVT_LISTBOX_DCLICK(Stratlas_Filelist, MyFrame::OnFilelist)
END_EVENT_TABLE()



// ----------------------------------------------------------------------------
// app class
// ----------------------------------------------------------------------------

bool StratlasApp::OnInit()
{
    wxFrame *frame = new MyFrame(NULL,0,wxT("Stratlas"));
    frame->Show();

    return true;
}

MyFrame::MyFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE)
{
    // begin wxGlade: MyFrame::MyFrame
    const wxString *list_box_1_choices = NULL;
    list_box_1 = new wxListBox(this, Stratlas_Worklist, wxDefaultPosition, wxDefaultSize, 0, list_box_1_choices, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_HSCROLL );
    button_1 = new wxButton(this, Stratlas_Add, wxT("Add"));
    button_2 = new wxButton(this, Stratlas_Remove, wxT("Remove"));
    const wxString *list_box_2_choices = NULL;
    list_box_2 = new wxListBox(this, Stratlas_Filelist, wxDefaultPosition, wxDefaultSize, 0, list_box_2_choices, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT);
    button_3 = new wxButton(this, Stratlas_Process, wxT("Process"));
    button_4 = new wxButton(this, Stratlas_Clear, wxT("Clear"));
    frame_1_menubar = new wxMenuBar();
    wxMenu* wxglade_tmp_menu_1 = new wxMenu();
    wxglade_tmp_menu_1->Append(wxID_ANY, wxT("Settings"), wxEmptyString, wxITEM_NORMAL);
    wxglade_tmp_menu_1->Append(Stratlas_Quit, wxT("Exit"), wxEmptyString, wxITEM_NORMAL);
    frame_1_menubar->Append(wxglade_tmp_menu_1, wxT("File"));
    wxMenu* wxglade_tmp_menu_2 = new wxMenu();
    wxglade_tmp_menu_2->Append(Stratlas_About, wxT("About"), wxEmptyString, wxITEM_NORMAL);
    wxglade_tmp_menu_2->Append(wxID_ANY, wxT("Contents"), wxEmptyString, wxITEM_NORMAL);
    frame_1_menubar->Append(wxglade_tmp_menu_2, wxT("Help"));
    SetMenuBar(frame_1_menubar);
    frame_1_statusbar = CreateStatusBar(1, 0);

    set_properties();
    do_layout();
    // end wxGlade

    // load stratlas.ini and get config info
#ifdef DEFINE_LOAD_WARCRAFT
    initWarcraft();
#endif
#ifdef DEFINE_LOAD_WAR2
    initWar2();
#endif
#ifdef DEFINE_LOAD_CNCTD
    initCNCTD();
#endif
#ifdef DEFINE_LOAD_TOTALA
    initTotalA();
#endif
FILE *cfgfile = NULL;
char buffer[256];
    cfgfile = fopen("stratlas.ini","r");
    while (!feof(cfgfile))
    {
      fgets(buffer,256,cfgfile);
      if (!feof(cfgfile) && buffer[0] != '\n' && buffer[0] != '#') {
#ifdef DEFINE_LOAD_WARCRAFT
      if (!cfgWarcraft(buffer))
#endif
#ifdef DEFINE_LOAD_WAR2
      if (!cfgWar2(buffer))
#endif
#ifdef DEFINE_LOAD_CNCTD
      if (!cfgCNCTD(buffer))
#endif
#ifdef DEFINE_LOAD_TOTALA
      if (!cfgTotalA(buffer))
#endif
      printf("Warning: unrecognized ini entry %s",buffer);
    }
}
    fclose(cfgfile);

    getcwd(path,1024);
    UpdateFileList(path);
}


void MyFrame::set_properties()
{
    // begin wxGlade: MyFrame::set_properties
    SetTitle(wxT("Stratlas"));
    SetSize(wxSize(640, 480));
    int frame_1_statusbar_widths[] = { -1 };
    frame_1_statusbar->SetStatusWidths(1, frame_1_statusbar_widths);
    const wxString frame_1_statusbar_fields[] = {
        wxT("Ready")
    };
    for(int i = 0; i < frame_1_statusbar->GetFieldsCount(); ++i) {
        frame_1_statusbar->SetStatusText(frame_1_statusbar_fields[i], i);
    }
    // end wxGlade
}


void MyFrame::do_layout()
{
    // begin wxGlade: MyFrame::do_layout
    wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_3 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_2 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_4 = new wxBoxSizer(wxVERTICAL);
    sizer_2->Add(list_box_1, 1, wxEXPAND, 0);
    sizer_4->Add(button_1, 0, 0, 0);
    sizer_4->Add(button_2, 0, 0, 0);
    sizer_2->Add(sizer_4, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 3);
    sizer_2->Add(list_box_2, 1, wxEXPAND, 0);
    sizer_1->Add(sizer_2, 1, wxEXPAND, 0);
    sizer_3->Add(button_3, 0, 0, 0);
    sizer_3->Add(button_4, 0, 0, 0);
    sizer_1->Add(sizer_3, 0, wxTOP|wxALIGN_CENTER_HORIZONTAL, 3);
    SetSizer(sizer_1);
    Layout();
    // end wxGlade

}

// event handlers
void MyFrame::OnButtonClear(wxCommandEvent& event)
{
    list_box_1->Clear();
    UpdateFileList(path);
}

void MyFrame::OnButtonAdd(wxCommandEvent& event)
{
  wxArrayInt selections;
  unsigned int numSelected,i,j,matched;
//  wxChar temp[1024];
  wxString temp;
  numSelected = list_box_2->GetSelections(selections);

  for (i=0;i<numSelected; i++)
  {
    if (list_box_2->GetString(selections[i])[0] != '(') {
      matched = 0;
      for (j=0; j<list_box_1->GetCount(); j++)
        if (wxStrcmp(list_box_1->GetString(j),list_box_2->GetString(selections[i])) == 0) { matched = 1; break; }
      if (!matched)
      {
	temp = wxString(path,wxConvUTF8) + wxT("/") + &list_box_2->GetString(selections[i])[3];
//        wxSprintf(temp,wxT("%s/%s"),path,&list_box_2->GetString(selections[i])[2]);
        list_box_1->Append(temp);
      }
    }
  }
}

void MyFrame::OnButtonRemove(wxCommandEvent& event)
{
  wxArrayInt selections;
  int numSelected,i;
  numSelected = list_box_1->GetSelections(selections);

  for (i=numSelected-1; i>=0; i--)
      list_box_1->Delete(selections[i]);
}

void MyFrame::OnButtonProcess(wxCommandEvent& event)
{
  FILE *fp;
  unsigned int i;
  struct MapFile map;
  struct Image *img;
  wxString str;

  for (i=0; i<list_box_1->GetCount(); i++)
  {
//      map.filename = (wxChar *)malloc(wxStrlen(list_box_1->GetString(i))+1);
//      wxStrcpy(map.filename,list_box_1->GetString(i));
	map.filename=list_box_1->GetString(i);
	str = wxT("Processing ") + map.filename + wxT("...");
//      wxSprintf(str,wxT("Processing %s..."),map.filename);
      frame_1_statusbar->SetStatusText(str,0);

      fp = fopen(map.filename.mb_str(),"rb");
      if (fp != NULL) {
        fseek(fp,0,SEEK_END);
        map.size = ftell(fp);
        rewind(fp);
        map.data = (unsigned char*)malloc(map.size);
        if (map.data) {
          fread(map.data,1,map.size,fp);
          img = NULL;
          if (0) { } // dummy
#ifdef DEFINE_LOAD_WARCRAFT
          else if (isWarcraft(map)) { img = renderWarcraft(map); }
#endif
#ifdef DEFINE_LOAD_WAR2
          else if (isWar2(map)) { img = renderWar2(map); }
#endif
#ifdef DEFINE_LOAD_CNCTD
          else if (isCNCTD(map)) { img = renderCNCTD(map); }
#endif
#ifdef DEFINE_LOAD_TOTALA
          else if (isTotalA(map)) { img = renderTotalA(map); }
#endif
          if (img != NULL) {
		str = map.filename + wxT(".png");
//            sprintf(str,"%s.png",map.filename);
            savePNG(img,str.mb_str());
            free(img->imgdata);
            free(img);
            img = NULL;
          }
          free(map.data);
          map.data = NULL;
        }
        fclose(fp);
        fp = NULL;
      }
//      free(map.filename);
  }
  frame_1_statusbar->SetStatusText(wxT("Ready"),0);
  UpdateFileList(path);
}

void MyFrame::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
{
  Close( TRUE );
}

void MyFrame::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
{
//  char msg[1024];
  wxString msg;

  msg = wxT("Stratlas v") + wxString(VERSION,wxConvUTF8) + wxT("\nCopyright 2008 Greg Kennedy, released under GNU GPL v3.\nhttp://stratlas.sourceforge.net\n\nCompiled with:\n");
  #ifdef DEFINE_LOAD_WARCRAFT
  msg += wxT(" DEFINE_LOAD_WARCRAFT");
  #endif
  #ifdef DEFINE_LOAD_WAR2
  msg += wxT(" DEFINE_LOAD_WAR2");
  #endif
  #ifdef DEFINE_LOAD_CNCTD
  msg += wxT(" DEFINE_LOAD_CNCTD");
  #endif
  #ifdef DEFINE_LOAD_TOTALA
  msg += wxT(" DEFINE_LOAD_TOTALA");
  #endif
  msg += wxT("\n");
  #ifdef DEFINE_SAVE_BMP
  msg += wxT(" DEFINE_SAVE_BMP");
  #endif
  #ifdef DEFINE_SAVE_PNG
  msg += wxT(" DEFINE_SAVE_PNG");
  #endif
  wxMessageBox( msg, wxT("About Stratlas"), wxOK | wxICON_INFORMATION );
}

void MyFrame::OnWorklist(wxCommandEvent& event)
{
  wxArrayInt selections;
  int numSelected,i;
  numSelected = list_box_1->GetSelections(selections);

  for (i=numSelected-1; i>=0; i--)
      list_box_1->Delete(selections[i]);
}

void MyFrame::OnFilelist(wxCommandEvent& event)
{
  wxArrayInt selections;
  unsigned int numSelected,i,j,matched;
//  wxChar temp[1024];
  wxString temp;
//  char newpath[128];
  numSelected = list_box_2->GetSelections(selections);

  for (i=0;i<numSelected; i++)
  {
    if (wxStrncmp(list_box_2->GetString(selections[i]),wxT("("),wxStrlen(wxT("("))) == 0) // chdir
    {
      strcat(path,"/");
//	strcpy(newpath,,&list_box_2->GetString(selections[i])[4].mb_str());
	temp = &list_box_2->GetString(selections[i])[4];
      strcat(path,temp.mb_str());
      chdir(path);
      getcwd(path,1024);
      UpdateFileList(path);
    } else {
      matched = 0;
      for (j=0; j<list_box_1->GetCount(); j++)
        if (wxStrcmp(list_box_1->GetString(j),list_box_2->GetString(selections[i])) == 0) { matched = 1; break; }
      if (!matched)
      {
        temp = wxString(path,wxConvUTF8) + wxT("/") + &list_box_2->GetString(selections[i])[3];
//        wxSprintf(temp,wxT("%s/%s"),path,&list_box_2->GetString(selections[i])[2]);
        list_box_1->Append(temp);
      }
    }
  }
}

// helper
void MyFrame::UpdateFileList(char *path)
{
     DIR *pdir, *dirtest;
     struct dirent *dir;
//     wxChar str[1024];
	wxString str;

     list_box_2->Clear();

     pdir = opendir(path);
     if (pdir == NULL) return;
     while ((dir = readdir(pdir)) != NULL)
     {
       dirtest = opendir(dir->d_name);
       if (dirtest != NULL)
	str = wxT("(D) ") + wxString(dir->d_name,wxConvUTF8);
//        wxSprintf(str,wxT("D - %s"),dir->d_name);
       else
	str = wxT("f: ") + wxString(dir->d_name,wxConvUTF8);
//         wxSprintf(str,wxT(": %s"),dir->d_name);
       closedir(dirtest);
       list_box_2->Append(str);
     }
     closedir(pdir);

  frame_1_statusbar->SetStatusText(wxString(path,wxConvUTF8),0);
}
